Load packages
library(tidyverse)
library(gridExtra)
library(cowplot)
library(ggridges)
library(ggstance)
library(treeio)
library(ggtree)
library(tidytree)
Load and combine data
species <- read_csv("../data/species_data.csv") %>% select(-species)
data <- read_csv("../data/data.csv") %>%
left_join(species, by = c("species" = "species_formatted")) %>%
rename(label = species_latin)
data2 <- data %>% group_by(species, label) %>% summarise(n = sum(n))
fulltree <- read.nexus("../data/consensusTree_10kTrees_298Primates_V3.nex")
refs <- read_csv("../data/ref_nodes.csv")
# turn tree into tidy dataframe
tree2 <- as_tibble(fulltree)
tree3 <- tree2 %>%
left_join(data2) %>%
mutate(
hasN = ifelse(is.na(n), 0, .5),
hasN2 = ifelse(is.na(n), .1, .5)) %>%
left_join(refs) %>%
# # also merge w datasheet listing node, n for inner nodes
# left_join(Ns, by = "node") %>%
# mutate(n = coalesce(n.x, n.y)) %>%
# select(-n.x, -n.y) %>%
groupClade(c(493, 496, 429, 302, 408)) %>%
mutate(group = fct_recode(group, "2" = "1"))
Joining, by = "label"
Joining, by = "node"
# turn back into tree
tree4 <- as.treedata(tree3)
Circular tree of 298 primates
cols <- viridis::viridis(4, end = .9)
# base plot
p <- ggtree(tree4, aes(size = hasN, alpha = hasN2), layout = "circular") +
# root
geom_rootpoint(size = 1) +
# tips
geom_tippoint(aes(size = n), alpha = .5) +
geom_tiplab2(aes(alpha = hasN), offset = 2, size = 3) +
# tweak scales
scale_alpha_continuous(range = c(.3, 1)) +
scale_size_continuous(range = c(.5, 8)) +
# widen plotting area
xlim(NA, 100)
# highlight clades with background colors
p2 <- p +
geom_hilight(node = 493, fill = cols[1], alpha = .3) +
geom_hilight(node = 496, fill = cols[1], alpha = .3) +
geom_hilight(node = 429, fill = cols[2], alpha = .3) +
geom_hilight(node = 303, fill = cols[3], alpha = .3) +
geom_hilight(node = 408, fill = cols[4], alpha = .3) +
# plot tree again to be on top of the highlights
geom_tree() +
geom_rootpoint(size = 1)
# highlight clades with branch colors
p3 <- p +
aes(col = group) +
scale_color_manual(values = c("gray30", cols))
plots <- mget(c("p", "p2", "p3"))
grid.arrange(p, p2, p3, nrow = 1)

# png with 3x1
ggsave("../graphs/phylo_full.png", arrangeGrob(grobs = plots, nrow = 1),
width = 24, height = 8, scale = 2, dpi = 72)
Removed 287 rows containing missing values (geom_point_g_gtree).Removed 287 rows containing missing values (geom_point_g_gtree).Removed 287 rows containing missing values (geom_point_g_gtree).
# pdf with 1 per page
ggsave("../graphs/phylo_full.pdf", marrangeGrob(grobs = plots, nrow = 1, ncol = 1),
width = 8, height = 8, scale = 2, dpi = 72)
Removed 287 rows containing missing values (geom_point_g_gtree).Removed 287 rows containing missing values (geom_point_g_gtree).Removed 287 rows containing missing values (geom_point_g_gtree).
Sample size in detail
# subset tree to just those species who have sample sizes reported, i.e. those who were tested
to_drop <- tree3 %>% filter(is.na(n)) %>% pull(label)
tree5 <- drop.tip(tree4, to_drop)
# make NA when equal to d4$Mdn
d4 <- full_join(d4a, d4b) %>%
mutate(Mdn_site2 = ifelse(Mdn == Mdn_site2, NA, Mdn_site2))
Joining, by = c("label", "species")

ggsave("../graphs/phylo_ridge_site.png", width = 4, height = 3, scale = 2)
Session info
sessionInfo()
R version 3.6.1 (2019-07-05)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS Mojave 10.14.5
Matrix products: default
BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/3.6/Resources/lib/libRlapack.dylib
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] tidytree_0.2.8 ggtree_1.16.6 treeio_1.8.2 ggstance_0.3.3 ggridges_0.5.1
[6] cowplot_1.0.0 gridExtra_2.3 forcats_0.4.0 stringr_1.4.0 dplyr_0.8.3
[11] purrr_0.3.2 readr_1.3.1 tidyr_1.0.0 tibble_2.1.3 ggplot2_3.2.1
[16] tidyverse_1.2.1
loaded via a namespace (and not attached):
[1] tidyselect_0.2.5 xfun_0.10 reshape2_1.4.3 haven_2.1.1 lattice_0.20-38
[6] colorspace_1.4-1 vctrs_0.2.0 generics_0.0.2 viridisLite_0.3.0 rlang_0.4.0
[11] pillar_1.4.2 glue_1.3.1 withr_2.1.2 modelr_0.1.5 readxl_1.3.1
[16] rvcheck_0.1.5 lifecycle_0.1.0 plyr_1.8.4 munsell_0.5.0 gtable_0.3.0
[21] cellranger_1.1.0 rvest_0.3.4 labeling_0.3 knitr_1.25 parallel_3.6.1
[26] broom_0.5.2 Rcpp_1.0.2 BiocManager_1.30.7 scales_1.0.0 backports_1.1.5
[31] jsonlite_1.6 hms_0.5.1 stringi_1.4.3 grid_3.6.1 cli_1.1.0
[36] tools_3.6.1 magrittr_1.5 lazyeval_0.2.2 crayon_1.3.4 ape_5.3
[41] pkgconfig_2.0.3 zeallot_0.1.0 xml2_1.2.2 lubridate_1.7.4 viridis_0.5.1
[46] assertthat_0.2.1 httr_1.4.1 rstudioapi_0.10 R6_2.4.0 nlme_3.1-141
[51] compiler_3.6.1
LS0tCnRpdGxlOiAiUGh5bG9nZW5ldGljIFRyZWUiCm91dHB1dDogCiAgaHRtbF9ub3RlYm9vazoKICAgIGNzczogc3R5bGUuY3NzCiAgICB0aGVtZTogcGFwZXIKLS0tCgpMb2FkIHBhY2thZ2VzCgpgYGB7ciwgbWVzc2FnZT1GQUxTRX0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoZ3JpZEV4dHJhKQpsaWJyYXJ5KGNvd3Bsb3QpCmxpYnJhcnkoZ2dyaWRnZXMpCmxpYnJhcnkoZ2dzdGFuY2UpCmxpYnJhcnkodHJlZWlvKQpsaWJyYXJ5KGdndHJlZSkKbGlicmFyeSh0aWR5dHJlZSkKYGBgCgpMb2FkIGFuZCBjb21iaW5lIGRhdGEKCmBgYHtyLCBtZXNzYWdlPUZBTFNFfQpzcGVjaWVzIDwtIHJlYWRfY3N2KCIuLi9kYXRhL3NwZWNpZXNfZGF0YS5jc3YiKSAlPiUgc2VsZWN0KC1zcGVjaWVzKQpkYXRhIDwtIHJlYWRfY3N2KCIuLi9kYXRhL2RhdGEuY3N2IikgJT4lIAogIGxlZnRfam9pbihzcGVjaWVzLCBieSA9IGMoInNwZWNpZXMiID0gInNwZWNpZXNfZm9ybWF0dGVkIikpICU+JSAKICByZW5hbWUobGFiZWwgPSBzcGVjaWVzX2xhdGluKQpkYXRhMiA8LSBkYXRhICU+JSBncm91cF9ieShzcGVjaWVzLCBsYWJlbCkgJT4lIHN1bW1hcmlzZShuID0gc3VtKG4pKQpmdWxsdHJlZSA8LSByZWFkLm5leHVzKCIuLi9kYXRhL2NvbnNlbnN1c1RyZWVfMTBrVHJlZXNfMjk4UHJpbWF0ZXNfVjMubmV4IikKcmVmcyA8LSByZWFkX2NzdigiLi4vZGF0YS9yZWZfbm9kZXMuY3N2IikKYGBgCgpgYGB7cn0KIyB0dXJuIHRyZWUgaW50byB0aWR5IGRhdGFmcmFtZQp0cmVlMiA8LSBhc190aWJibGUoZnVsbHRyZWUpCgp0cmVlMyA8LSB0cmVlMiAlPiUgCiAgbGVmdF9qb2luKGRhdGEyKSAlPiUgCiAgbXV0YXRlKAogICAgaGFzTiA9IGlmZWxzZShpcy5uYShuKSwgMCwgLjUpLAogICAgaGFzTjIgPSBpZmVsc2UoaXMubmEobiksIC4xLCAuNSkpICU+JSAKICBsZWZ0X2pvaW4ocmVmcykgJT4lIAogICMgIyBhbHNvIG1lcmdlIHcgZGF0YXNoZWV0IGxpc3Rpbmcgbm9kZSwgbiBmb3IgaW5uZXIgbm9kZXMKICAjIGxlZnRfam9pbihOcywgYnkgPSAibm9kZSIpICU+JSAKICAjIG11dGF0ZShuID0gY29hbGVzY2Uobi54LCBuLnkpKSAlPiUgCiAgIyBzZWxlY3QoLW4ueCwgLW4ueSkgJT4lIAogIGdyb3VwQ2xhZGUoYyg0OTMsIDQ5NiwgNDI5LCAzMDIsIDQwOCkpICU+JSAKICBtdXRhdGUoZ3JvdXAgPSBmY3RfcmVjb2RlKGdyb3VwLCAiMiIgPSAiMSIpKQoKIyB0dXJuIGJhY2sgaW50byB0cmVlCnRyZWU0IDwtIGFzLnRyZWVkYXRhKHRyZWUzKQpgYGAKCiMgRmlndXJlIG91dCBub2RlcwoKVGhpcyBtYWtlcyBhIHJlY3Rhbmd1bGFyIGFuZCBhIGNpcmN1bGFyIHRyZWUgd2l0aCB0aGUgbm9kZSBudW1iZXJzIGRpc3BsYXllZCBmb3IgcmVmZXJlbmNlIChzYXZlZCBpbiB0aGUgYGdyYXBoc2AgZm9sZGVyKS4KCmBgYHtyfQp0cmVlMy4yIDwtIGFzLnRyZWVkYXRhKHRyZWUzKQpgYGAKCmBgYHtyLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD0yMCwgZXZhbD1GQUxTRX0KIyBkaXNwbGF5IG5vZGUgbnVtYmVycyBmb3IgcmVmZXJlbmNlCmdndHJlZSh0cmVlMy4yKSArCiAgIyB0aXAgbGFiZWxzCiAgZ2VvbV90aXBwb2ludChhZXMoc2l6ZSA9IG4pLCBjb2wgPSAic2VhZ3JlZW4iLCBhbHBoYSA9IC41KSArCiAgZ2VvbV90aXBsYWIob2Zmc2V0ID0gMSwgc2l6ZSA9IDMpICsKICAjIG5vZGUgbGFiZWxzCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IG5vZGUsIHggPSBicmFuY2gpLCBzaXplID0gMiwgY29sID0gImJsdWUiLCB2anVzdCA9IC0uNSkgKwogIGV4cGFuZF9saW1pdHMoeCA9IDkwKSArCiAgIyBkaXNwbGF5IHRpbWVzY2FsZSBhdCB0aGUgYm90dG9tCiAgdGhlbWVfdHJlZTIoKQpgYGAKCmBgYHtyLCBldmFsPUZBTFNFfQpnZ3NhdmUoIi4uL2dyYXBocy9mdWxsX3RyZWVfbm9kZXMucGRmIiwgd2lkdGggPSA4LCBoZWlnaHQgPSAyMCwgc2NhbGUgPSAyKQpgYGAKCmBgYHtyLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD04LCBldmFsPUZBTFNFfQpnZ3RyZWUodHJlZTMuMiwgbGF5b3V0ID0gImNpcmN1bGFyIikgKwogIGdlb21fdGlwcG9pbnQoYWVzKHNpemUgPSBuKSwgY29sID0gInNlYWdyZWVuIiwgYWxwaGEgPSAuNSkgKwogIGdlb21fdGlwbGFiMihvZmZzZXQgPSAyLCBzaXplID0gMykgKwogIGdlb21fdGV4dDIoYWVzKGxhYmVsID0gbm9kZSksIHNpemUgPSAxLjUsIGNvbCA9ICJibHVlIikgKwogIHhsaW0oTkEsIDEwMCkKYGBgCgpgYGB7ciwgZXZhbD1GQUxTRX0KZ2dzYXZlKCIuLi9ncmFwaHMvZnVsbF90cmVlX25vZGVzX2NpcmN1bGFyLnBkZiIsIHdpZHRoID0gOCwgaGVpZ2h0ID0gOCwgc2NhbGUgPSAyKQpgYGAKCiMgQ2lyY3VsYXIgdHJlZSBvZiAyOTggcHJpbWF0ZXMKCmBgYHtyfQpjb2xzIDwtIHZpcmlkaXM6OnZpcmlkaXMoNCwgZW5kID0gLjkpCmBgYAoKYGBge3J9CiMgYmFzZSBwbG90CnAgPC0gZ2d0cmVlKHRyZWU0LCBhZXMoc2l6ZSA9IGhhc04sIGFscGhhID0gaGFzTjIpLCBsYXlvdXQgPSAiY2lyY3VsYXIiKSArCiAgIyByb290CiAgZ2VvbV9yb290cG9pbnQoc2l6ZSA9IDEpICsKICAjIHRpcHMKICBnZW9tX3RpcHBvaW50KGFlcyhzaXplID0gbiksIGFscGhhID0gLjUpICsKICBnZW9tX3RpcGxhYjIoYWVzKGFscGhhID0gaGFzTiksIG9mZnNldCA9IDIsIHNpemUgPSAzKSArCiAgIyB0d2VhayBzY2FsZXMKICBzY2FsZV9hbHBoYV9jb250aW51b3VzKHJhbmdlID0gYyguMywgMSkpICsKICBzY2FsZV9zaXplX2NvbnRpbnVvdXMocmFuZ2UgPSBjKC41LCA4KSkgKwogICMgd2lkZW4gcGxvdHRpbmcgYXJlYQogIHhsaW0oTkEsIDEwMCkKYGBgCgpgYGB7cn0KIyBoaWdobGlnaHQgY2xhZGVzIHdpdGggYmFja2dyb3VuZCBjb2xvcnMKcDIgPC0gcCArIAogIGdlb21faGlsaWdodChub2RlID0gNDkzLCBmaWxsID0gY29sc1sxXSwgYWxwaGEgPSAuMykgKwogIGdlb21faGlsaWdodChub2RlID0gNDk2LCBmaWxsID0gY29sc1sxXSwgYWxwaGEgPSAuMykgKwogIGdlb21faGlsaWdodChub2RlID0gNDI5LCBmaWxsID0gY29sc1syXSwgYWxwaGEgPSAuMykgKwogIGdlb21faGlsaWdodChub2RlID0gMzAzLCBmaWxsID0gY29sc1szXSwgYWxwaGEgPSAuMykgKwogIGdlb21faGlsaWdodChub2RlID0gNDA4LCBmaWxsID0gY29sc1s0XSwgYWxwaGEgPSAuMykgKwogICMgcGxvdCB0cmVlIGFnYWluIHRvIGJlIG9uIHRvcCBvZiB0aGUgaGlnaGxpZ2h0cwogIGdlb21fdHJlZSgpICsKICBnZW9tX3Jvb3Rwb2ludChzaXplID0gMSkKYGBgCgpgYGB7cn0KIyBoaWdobGlnaHQgY2xhZGVzIHdpdGggYnJhbmNoIGNvbG9ycwpwMyA8LSBwICsgCiAgYWVzKGNvbCA9IGdyb3VwKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoImdyYXkzMCIsIGNvbHMpKQpgYGAKCmBgYHtyfQpwbG90cyA8LSBtZ2V0KGMoInAiLCAicDIiLCAicDMiKSkKYGBgCgpgYGB7ciwgZmlnLndpZHRoPTE4LCBmaWcuaGVpZ2h0PTZ9CmdyaWQuYXJyYW5nZShwLCBwMiwgcDMsIG5yb3cgPSAxKQpgYGAKCmBgYHtyfQojIHBuZyB3aXRoIDN4MQpnZ3NhdmUoIi4uL2dyYXBocy9waHlsb19mdWxsLnBuZyIsIGFycmFuZ2VHcm9iKGdyb2JzID0gcGxvdHMsIG5yb3cgPSAxKSwgCiAgICAgICB3aWR0aCA9IDI0LCBoZWlnaHQgPSA4LCBzY2FsZSA9IDIsIGRwaSA9IDcyKQoKIyBwZGYgd2l0aCAxIHBlciBwYWdlCmdnc2F2ZSgiLi4vZ3JhcGhzL3BoeWxvX2Z1bGwucGRmIiwgbWFycmFuZ2VHcm9iKGdyb2JzID0gcGxvdHMsIG5yb3cgPSAxLCBuY29sID0gMSksIAogICAgICAgd2lkdGggPSA4LCBoZWlnaHQgPSA4LCBzY2FsZSA9IDIsIGRwaSA9IDcyKQpgYGAKCiMgU2FtcGxlIHNpemUgaW4gZGV0YWlsCgpgYGB7cn0KIyBzdWJzZXQgdHJlZSB0byBqdXN0IHRob3NlIHNwZWNpZXMgd2hvIGhhdmUgc2FtcGxlIHNpemVzIHJlcG9ydGVkLCBpLmUuIHRob3NlIHdobyB3ZXJlIHRlc3RlZAp0b19kcm9wIDwtIHRyZWUzICU+JSBmaWx0ZXIoaXMubmEobikpICU+JSBwdWxsKGxhYmVsKQp0cmVlNSA8LSBkcm9wLnRpcCh0cmVlNCwgdG9fZHJvcCkKYGBgCgpgYGB7cn0KZGF0YTMgPC0gZGF0YSAlPiUgCiAgc2VsZWN0KGxhYmVsLCBldmVyeXRoaW5nKCkpICU+JSAKICByZW5hbWUobnVtID0gbikKCiMgc3BlY2llcyB3aXRoIG1vcmUgdGhhbiBYIHNpdGVzIGNhbiBnZXQgYSBkZW5zaXR5PwpkM2EgPC0gZGF0YTMgJT4lIGdyb3VwX2J5KHNwZWNpZXMpICU+JSBmaWx0ZXIobl9kaXN0aW5jdChzaXRlKSA+PSA0KQpkM2IgPC0gZGF0YTMgJT4lICMgc2V0ZGlmZihkYXRhMywgZDNhKSAjIyA8LSBkbyBzZXRkaWZmIGluc3RlYWQgdG8gTk9UIHNob3cgcG9pbnRzIGZvciBkZW5zaXRpZXMKICBncm91cF9ieShzcGVjaWVzKSAlPiUgCiAgIyBjcmVhdGUgdmFyaWFibGUgbnVtMiBpcyBOQSBpZiB0aGVyZSdzIG9ubHkgb25lIGRhdGEgcG9pbnQgZm9yIGEgc3BlY2llcwogICMgLS0+IHRob3NlIHNwZWNpZXMgd2lsbCBvbmx5IGdldCB0aGUgdmVydGljYWwgY3Jvc3NiYXIKICBtdXRhdGUoZmxhZyA9IG5fZGlzdGluY3Qoc2l0ZSkgPT0gMSkgJT4lIAogIHVuZ3JvdXAgJT4lIAogIG11dGF0ZShudW0yID0gaWZlbHNlKGZsYWcsIE5BLCBudW0pKQoKIyBmb3IgdmVydGljYWwgY3Jvc3NiYXIgPSBtZWRpYW4KZDRhIDwtIGRhdGEzICU+JSAKICBncm91cF9ieShsYWJlbCwgc3BlY2llcykgJT4lIAogIHN1bW1hcmlzZShNZG4gPSBtZWRpYW4obnVtKSkgIyB0b3RhbE4gPSBzdW0obnVtKSwgc2l0ZXNOID0gbl9kaXN0aW5jdChzaXRlKQoKIyBmb3IgY3Jvc3MgPSBtZWRpYW4gKHNhbXBsZSBzaXplIGJ5IHNwZWNpZXMgYW5kIHNpdGUpCmQ0YiA8LSBkYXRhMyAlPiUgCiAgZ3JvdXBfYnkobGFiZWwsIHNwZWNpZXMsIHNpdGUpICU+JSAKICBzdW1tYXJpc2UoTWRuX3NpdGUgPSBtZWRpYW4obnVtKSklPiUgCiAgZ3JvdXBfYnkobGFiZWwsIHNwZWNpZXMpICU+JSAKICBzdW1tYXJpc2UoTWRuX3NpdGUyID0gbWVkaWFuKE1kbl9zaXRlKSkKCiMgbWFrZSBOQSB3aGVuIGVxdWFsIHRvIGQ0JE1kbgpkNCA8LSBmdWxsX2pvaW4oZDRhLCBkNGIpICU+JSAKICBtdXRhdGUoTWRuX3NpdGUyID0gaWZlbHNlKE1kbiA9PSBNZG5fc2l0ZTIsIE5BLCBNZG5fc2l0ZTIpKQoKIyBmb3IgdmVydGljYWwgbGluZSBpbiByaWRnZSBwbG90IChncmFuZCBtZWRpYW4pCiMgKyBoYWNreSB3YXkgdG8gbWFrZSBob3Jpem9udGFsIGdyaWQgbGluZXMgZm9yIHJpZ2h0IHBhbmVsIG9ubHkKdiA8LSB0aWJibGUocmVmZXJlbmNlID0gYyhOQSwgbWVkaWFuKGRhdGEzJG51bSkpLCAucGFuZWwgPSBjKCJUcmVlIiwgInhTYW1wbGUgc2l6ZSIpKQpoIDwtIHRpYmJsZShyZWZlcmVuY2UgPSBjKE5BLCAxOk50aXAodHJlZTUpKSwgLnBhbmVsID0gYygiVHJlZSIsIHJlcCgieFNhbXBsZSBzaXplIiwgTnRpcCh0cmVlNSkpKSkKCiMgZm9yIGF4aXMgbGFiZWxzCmF4IDwtIHRpYmJsZShsYWIgPSBjKCJEaXN0YW5jZSIsICJTYW1wbGUgc2l6ZSIpLCB4ID0gYyg2Ny41LCBtYXgoZGF0YTMkbnVtKS8yKSwgeSA9IC0uMywgCiAgICAgICAgICAgICAucGFuZWwgPSBjKCJUcmVlIiwgInhTYW1wbGUgc2l6ZSIpKQpgYGAKCmBgYHtyLCBmaWcud2lkdGg9NCwgZmlnLmhlaWdodD0zfQojIHJpZ2h0LXNpZGUgdml6IGRlcGVuZHMgb24gdGhlIG51bWJlciBvZiBzaXRlcyBwZXIgc3BlY2llczoKIyAxIHNpdGUgPSB2ZXJ0aWNhbCBjcm9zc2JhciBvbmx5CiMgMisgc2l0ZXMgPSBwb2ludHMgKyBjcm9zc2JhciBhdCBtZWRpYW4KIyBYKyBzaXRlcyA9IGRlbnNpdGllcyAoY3VycmVudGx5LCBYID0gNCBqdXN0IHRvIGlsbHVzdHJhdGUpCgojIGRpcnR5IGhhY2s6IHggaW4gZnJvbnQgb2YgIlNhbXBsZSBzaXplIiBpcyB0byBoYXZlIHRoYXQgcGFuZWwgc29ydCB0byB0aGUgcmlnaHQgKGFscGhhYmV0aWNhbGx5KSB1bnRpbCBJIGZpZ3VyZSBvdXQgd2h5IGl0IGRvZXNuJ3QganVzdCBnbyBieSBvcmRlci4gVGhpcyBjcm9wcGVkIHVwIGFzIGFuIGlzc3VlIHdoZW4gSSBhZGRlZCB0aGUgZHVtbXkgcG9pbnQgZm9yIHRoZSB4LWF4aXMgZXhwYW5zaW9uLi4uCgojIExFRlQgRkFDRVQKcSA8LSBnZ3RyZWUodHJlZTUsIGFlcyhjb2wgPSBncm91cCkpICsKICAjIHRoaXMgaXMgYSBkdW1teSBwb2ludCB0byBleHBhbmQgdGhlIHggc2NhbGUKICAjIHRoZSB0eXBpY2FsIHdheXMgd2VpcmRseSBhbHNvIGV4cGFuZCBpdCBmb3IgdGhlIHNhbXBsZSBzaXplIHBhbmVsIG9uY2UgdGhhdCdzIGFkZGVkCiAgIyBnZW9tX3BvaW50KGRhdGEgPSB0aWJibGUoeCA9IDEzNSwgeSA9IDEsIC5wYW5lbCA9ICJUcmVlIiwgZ3JvdXAgPSBOQSkpICsKICAjIHRpcCBsYWJlbHMKICBnZW9tX3RpcHBvaW50KGFlcyhzaXplID0gbiksIGFscGhhID0gLjUpICsKICBnZW9tX3RpcGxhYihvZmZzZXQgPSA0LCBzaXplID0gMykgKwogICMgdHdlYWsgc2NhbGVzCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoImdyZXkzMCIsIGNvbHMpKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY29sc1s0XSkgKyAjIHdoZW4gYWxsIGNhdGVnb3JpZXMgYXJlIHRha2VuOiBjb2xzCiAgIyBkaXNwbGF5IHRpbWVzY2FsZSBhdCB0aGUgYm90dG9tCiAgdGhlbWVfdHJlZTIoKSArCiAgeGxpbV90cmVlKDEzNSkgKwogICMgYWRkIGF4aXMgbGFiZWxzCiAgZ2VvbV90ZXh0KGRhdGEgPSBheCwgYWVzKGxhYmVsID0gbGFiKSwgY29sID0gImJsYWNrIikgKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDEsIE50aXAodHJlZTUpKSwgb29iID0gZnVuY3Rpb24oeCwgLi4uKSB4KSArCiAgY29vcmRfY2FydGVzaWFuKGNsaXAgPSAib2ZmIikgKwogICMgYWRkIHJlZmVyZW5jZSBsaW5lcyAodGhlc2Ugd2lsbCBzaG93IHVwIG9uIHJpZ2h0IHBhbmVsIG9mIGZhY2V0X3Bsb3Qgb25seSkKICBnZW9tX2hsaW5lKGRhdGEgPSBoLCBhZXMoeWludGVyY2VwdCA9IHJlZmVyZW5jZSksIGx3ZCA9IC4yLCBjb2wgPSAiZ3JleSIsIGFscGhhID0gLjUpICsKICBnZW9tX3ZsaW5lKGRhdGEgPSB2LCBhZXMoeGludGVyY2VwdCA9IHJlZmVyZW5jZSksIGx3ZCA9IDEuNSwgY29sID0gImdyZXkiLCBhbHBoYSA9IC4zKSArCiAgIyByZW1vdmUgZmFjZXQgc3RyaXBzCiAgIyBvciBlbGVtZW50X3RleHQoc2l6ZSA9IDE0KQogIHRoZW1lKHN0cmlwLnRleHQgPSBlbGVtZW50X2JsYW5rKCksIHN0cmlwLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGxvdC5tYXJnaW4gPSB1bml0KGMoLjUsIC41LCAxLjIsIC41KSwgImNtIikpCgojIEFERCBSSUdIVCBGQUNFVApxICU+JSAKICAjIGRlbnNpdGllcyBmb3Igc3BlY2llcyB3aXRoIGVub3VnaCBzaXRlcwogIGZhY2V0X3Bsb3QoInhTYW1wbGUgc2l6ZSIsIGQzYSwgZ2VvbV9kZW5zaXR5X3JpZGdlcywgYWVzKHggPSBudW0sIGdyb3VwID0gbGFiZWwsIGZpbGwgPSBncm91cCksIAogICAgICAgICAgICAgYWxwaGEgPSAuNSwgbHdkID0gLjMsIHBvc2l0aW9uID0gcG9zaXRpb25fbnVkZ2UoeSA9IC4xKSkgJT4lIAogICMgdmVydGljYWwgY3Jvc3NiYXIgZm9yIE1kbgogIGZhY2V0X3Bsb3QoInhTYW1wbGUgc2l6ZSIsIGQ0LCBnZW9tX2Nyb3NzYmFyaCwgYWVzKHggPSBNZG4sIHhtaW4gPSBNZG4sIHhtYXggPSBNZG4sIGdyb3VwID0gbGFiZWwsIAogICAgICAgICAgICAgY29sID0gZ3JvdXApLCBhbHBoYSA9IC41LCB3aWR0aCA9IC4zKSAlPiUKICAjIHggZm9yIE1kbl9zaXRlCiAgZmFjZXRfcGxvdCgieFNhbXBsZSBzaXplIiwgZDQsIGdlb21fcG9pbnQsIGFlcyh4ID0gTWRuX3NpdGUyLCBncm91cCA9IGxhYmVsKSwgc2hhcGUgPSA0LCBzaXplID0gMiwgc3Ryb2tlID0gMS41LCBhbHBoYSA9IC44KSAlPiUKICAjIHZlcnRpY2FsIG1hcmsgZm9yIGluZGl2aWR1YWwgc2l0ZXMKICBmYWNldF9wbG90KCJ4U2FtcGxlIHNpemUiLCBkM2IsIGdlb21fcG9pbnQsIGFlcyh4ID0gbnVtMiwgZ3JvdXAgPSBsYWJlbCksIHNoYXBlID0gInwiLCBzaXplID0gMykgIysKYGBgCgpgYGB7cn0KZ2dzYXZlKCIuLi9ncmFwaHMvcGh5bG9fcmlkZ2Vfc2l0ZS5wbmciLCB3aWR0aCA9IDQsIGhlaWdodCA9IDMsIHNjYWxlID0gMikKYGBgCgojIFNlc3Npb24gaW5mbwoKYGBge3J9CnNlc3Npb25JbmZvKCkKYGBgCgo=